package com.woniuxy.credit_loans.config;

import com.alibaba.fastjson.JSON;
import com.woniuxy.credit_loans.annotation.OperationLog;
import com.woniuxy.credit_loans.entity.LoginLogger;
import com.woniuxy.credit_loans.staff_ma.service.LoginLoggerService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @Author Cornelia
 * @Date 2022-12-11
 * @Description 添加用户操作日志 --马玉雪 2022/12/11
 **/
@Aspect
@Component
//自定义切面
public class LogAspect {

    @Autowired
    private LoginLoggerService loggerService;

    private static final Logger log = LoggerFactory.getLogger(LogAspect.class);

    //自定义注解作为切入点
    @Pointcut("execution(* com.woniuxy.credit_loans.staff_ma.controller..*(..))")
    public void point() {

    }

    //切点之前
    @Before("point()")
    public void doBfore(JoinPoint joinPoint) throws Throwable {
        log.info("---aop 日志记录启动---" + new Date());
    }

    //环绕增强,在before之前触发
    @Around("@annotation(operationLog)")
    @Transactional
    public Object doAround(ProceedingJoinPoint joinPoint, OperationLog operationLog) throws Throwable {

        LoginLogger loginLogger = new LoginLogger();
        log.info("---aop 日志环绕阶段---" + new Date());


        ServletRequestAttributes attributes
                = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        //通过request get参数
        String url = request.getRequestURL().toString();
        String value = operationLog.value();
        String method = request.getMethod();
        String addr = request.getRemoteAddr();
        Object[] objects = joinPoint.getArgs();
        ArrayList<Object> list = new ArrayList<>();
        for (Object obj : list) {
            //request response中无法使用toJSON
            if (obj instanceof HttpServletRequest) {
                list.add("request");
            } else if (obj instanceof HttpServletResponse) {
                list.add("response");
            } else {
                list.add(JSON.toJSON(obj));
            }
        }
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;

        //获取参数名，封装在数组中
        String[] parameterNames = ((MethodSignature) signature).getParameterNames();
        log.info("参数名数组：" + new ArrayList(Arrays.asList(parameterNames)));
        log.info("参数：" + list.toString());
        log.info("注解接口：" + operationLog);
        log.info("请求路径：" + url);
        log.info("ip地址：" + addr);
        log.info("请求方式：" + method);

        loginLogger.setLoggerTime(new Date());
        loginLogger.setIp(request.getRemoteAddr());
        loginLogger.setLoginMethod(((MethodSignature) signature).getMethod().getName());
        loggerService.insertSelective(loginLogger);
        return joinPoint.proceed();
    }


    //方法正常运行后返回
    @After("point()")
    public void doAfter(JoinPoint joinPoint) {
        log.info("---aop 日志记录结束---" + new Date());
    }

}
